<template>
    <rx-dialog class="rightDesign" @ok="handleSubmit" @cancel="cancel">
        <rx-layout>
            <template #middle>
                <div style="padding: 10px;width: 100%;height: 100%">
                    <a-form layout="vertical">
                        <a-row>
                            <a-col :span="12">
                                <a-form-item :label="i18n('common.event','事件')">
                                    <div class="eventFuncDialog-name">{{ eventItem.name }}</div>
                                </a-form-item>
                            </a-col>
                        </a-row>
                        <div>
                            <a-button @click="addMethod" type="primary">
                                <rx-icon-show icon="icon-lineVue3_add"></rx-icon-show>
                                {{ $ti18('rxList.addBtn', '新增') }}
                            </a-button>
                            <a-collapse style="margin-top: 10px" :default-active-key="0" :bordered="false">
                                <template #expandIcon="props">
                                    <caret-right-outlined :rotate="props.isActive ? 90 : 0"/>
                                </template>
                                <a-collapse-panel class="eventFuncDialog-panel" :key="index"
                                                  v-for="(methodItem,index) in eventConfig">
                                    <template #extra>
                                    <span @click.stop="">
                                        <div class="eventFuncDialog-extra">
                                            <div class="eventFuncDialog-file">
                                                <span>{{ i18n('common.calComponent', '调用组件') }}:</span>
                                                <div style="margin-left: 10px;flex: 1;">
                                                    <a-select v-model:value="methodItem.component" style="width: 200px;"
                                                              @change="componentChange($event,methodItem)">
                                                        <a-select-option v-for="(component,index) in allCustomComponent"
                                                                         :key="index" :value="component.name">
                                                            {{ component.comment }}
                                                        </a-select-option>
                                                    </a-select>
                                                </div>
                                            </div>
                                            <div class="eventFuncDialog-file" style="margin-left: 20px">
                                                <span>{{ i18n('common.calMethod', '调用方法') }}:</span>
                                                <div style="margin-left: 10px;flex: 1">
                                                    <a-select v-model:value="methodItem.method" style="width: 200px;"
                                                              @change="methodChange($event,methodItem)">
                                                        <a-select-option
                                                            v-for="(method,index) in (componentMethod[methodItem.component] || [] )"
                                                            :key="index" :value="method.name">{{ method.name }}
                                                        </a-select-option>
                                                    </a-select>
                                                </div>
                                            </div>
                                            <rx-icon-show class="delMethod" icon="icon-lineVue3_delete"
                                                          @click="delMethod(index)"></rx-icon-show>
                                        </div>
                                    </span>
                                    </template>
                                    <div style="padding: 20px">
                                        <a-table
                                            :dataSource="methodItem.params"
                                            :pagination="false"
                                            rowKey="idx_"
                                            size="small"
                                            :bordered="true"
                                        >
                                            <a-table-column :title="i18n('eventFuncDialog.methodParam','方法参数')" :width="200"
                                                            dataIndex="methodParam">
                                                <template #default="{ record }">
                                                    <div class="table-name">{{ record.methodParam }}</div>
                                                </template>
                                            </a-table-column>
                                            <a-table-column :title="i18n('common.valueSource','值来源')" :width="200"
                                                            dataIndex="valueSource">
                                                <template #default="{ record }">
                                                    <a-select
                                                        style="width: 200px;"
                                                        v-model:value="record.valueSource"
                                                        :options="valueSourceDef"
                                                        :allowClear="true"
                                                        @change="valueSourceChange(record)"
                                                    >
                                                    </a-select>
                                                </template>
                                            </a-table-column>
                                            <a-table-column :title="i18n('eventFuncDialog.eventValue','事件返回值')"
                                                            dataIndex="eventValue">
                                                <template #default="{ record }">
                                                    <a-select v-if="record.valueSource == 'param'" style="width: 200px;"
                                                              v-model:value="record.eventValue" :allowClear="true">
                                                        <a-select-option v-for="(param,index) in eventItem.params"
                                                                         :key="index" :value="param.name">
                                                            {{ param.name }}({{ param.comment }})
                                                        </a-select-option>
                                                    </a-select>
                                                    <a-input
                                                        v-else-if="record.valueSource == 'fixedVar' || record.valueSource == 'script'"
                                                        style="width: 200px;"
                                                        v-model:value="record.eventValue"></a-input>
                                                    <template v-else-if="record.valueSource == 'component'">
                                                        <div style="display: flex">
                                                            <div style="flex: 1">
                                                                <a-select v-model:value="record.component"
                                                                          style="width: 200px;"
                                                                          @change="getComponentProps($event,record)"
                                                                          :placeholder="i18n('common.component','组件')">
                                                                    <a-select-option
                                                                        v-for="(component,index) in allCustomComponent"
                                                                        :key="index" :value="component.name">
                                                                        {{ component.comment }}
                                                                    </a-select-option>
                                                                </a-select>
                                                            </div>
                                                            <div style="margin-left: 10px;flex: 1" v-if="record.component">
                                                                <a-select v-model:value="record.eventValue"
                                                                          style="width: 200px;"
                                                                          :placeholder="i18n('common.property','属性')">
                                                                    <a-select-option
                                                                        v-for="(props_,index) in (componentProps[record.component] || [] )"
                                                                        :key="index" :value="props_.name">
                                                                        {{ props_.comment }}
                                                                    </a-select-option>
                                                                </a-select>
                                                            </div>
                                                        </div>
                                                    </template>
                                                </template>
                                            </a-table-column>
                                        </a-table>
                                    </div>
                                </a-collapse-panel>
                            </a-collapse>
                        </div>
                    </a-form>
                </div>
            </template>
        </rx-layout>
    </rx-dialog>
</template>

<script>
import {Util, RxDialog, RxLayout} from "@lowcode/jpaas-base-lib";

export default {
    name: "EventFuncDialog",
    components: {RxDialog, RxLayout},
    props: {
        //大屏配置
        screenConfig: {
            type: Object
        },
        //组件配置
        config: {
            type: Object
        },
        //当前事件对象
        eventItem: {
            type: Object
        },
        destroy: {
            type: Function
        },
    },
    data() {
        return {
            eventConfig: [],
            allCustomComponent: [],//所有自定义组件
            componentMethod: {},//组件方法
            componentProps: {},//组件属性
            valueSourceDef: [
                {value: 'param', label: this.i18n('common.param', '参数')},
                {value: 'fixedVar', label: this.i18n('common.fixedValue', '固定值')},
                {value: 'component', label: this.i18n('common.component', "组件")},
                {value: 'script', label: this.i18n('common.script', "脚本")}
            ],
        }
    },
    created() {
        this.init();
    },
    methods: {
        i18n(name, text, key) {
            return this.$ti18(name, text, "dialogLang", key);
        },
        init() {
            let flag = false;
            if (this.eventItem.eventConfig) {
                this.eventConfig = JSON.parse(JSON.stringify(this.eventItem.eventConfig));
                flag = true;
            }
            this.getCustomComponents(flag);
        },
        //获取暴露的所有自定义组件
        getCustomComponents(flag) {
            let files = import.meta.glob('@/views/modules/custom-components/**/*.json');
            for (let i = 0; i < this.screenConfig.components.length; i++) {
                let component = this.screenConfig.components[i];
                if (component.type == "custom") {
                    let obj = {
                        customName: component.config.customName,
                        name: component.config.key,
                        comment: component.config.title
                    }
                    for (let path in files) {
                        files[path]().then(mod => {
                            let file = mod["default"];
                            if (file && file.name == obj.customName) {
                                obj = Object.assign(JSON.parse(JSON.stringify(file)), obj);
                                this.allCustomComponent.push(obj);
                            }
                        });
                    }
                }
            }
            //是否需要构建内部下拉框项
            if (flag) {
                for (let i = 0; i < this.eventConfig.length; i++) {
                    let eventConfig = this.eventConfig[i];
                    let component = this.allCustomComponent.find(item => {
                        if (item.name == eventConfig.component) {
                            return true;
                        }
                    })
                    if (!component) {
                        continue;
                    }
                    this.componentMethod[component.name] = component.methods;
                    let methodObj = component.methods.find(item => {
                        if (item.name == eventConfig.method) {
                            return true;
                        }
                    })
                    if (!methodObj) {
                        continue;
                    }
                    for (let i = 0; i < methodObj.params.length; i++) {
                        let paramObj = eventConfig.params.find(item => {
                            if (item.methodParam == methodObj.params[i].name) {
                                return true;
                            }
                        })
                        if (paramObj) {
                            continue;
                        }
                        eventConfig.params.push({
                            methodParam: methodObj.params[i].name,
                            valueSource: "",
                            eventValue: "",
                        })
                    }
                }
            }
        },
        addMethod() {
            this.eventConfig.push({
                component: "",//调用的组件
                method: "",//调用的方法
                params: [],//方法参数
            })
        },
        delMethod(index) {
            let self = this;
            this.$confirm({
                title: this.$ti18('rxMsa.actionTips', '操作提示'),
                zIndex: 20000,
                content: this.i18n("eventFuncDialog.delMsg", "您确定要删除当前配置吗？"),
                okText: this.$ti18('rxForm.ackBtn', '确认'),
                cancelText: this.$ti18('rxForm.cancelBtn', '取消'),
                onOk() {
                    self.eventConfig.splice(index, 1);
                },
                onCancel() {
                }
            })

        },
        handleSubmit() {
            Util.closeWindow(this, "ok", this.eventConfig);
        },
        cancel() {
            Util.closeWindow(this, "cancel");
        },
        componentChange(value, methodItem) {
            let component = this.allCustomComponent.find(item => {
                if (item.name == value) {
                    return true;
                }
            })
            if (!component) {
                return;
            }
            this.componentMethod[component.name] = component.methods;
            //清空
            methodItem.method = "";
            methodItem.params = [];
        },
        methodChange(value, methodItem) {
            let methodObj = this.componentMethod[methodItem.component].find(item => {
                if (item.name == value) {
                    return true;
                }
            })
            if (!methodObj) {
                return;
            }
            methodItem.params = [];
            for (let i = 0; i < methodObj.params.length; i++) {
                methodItem.params.push({
                    methodParam: methodObj.params[i].name,
                    valueSource: "",
                    eventValue: "",
                })
            }
        },
        getComponentProps(value, record) {
            let component = this.allCustomComponent.find(item => {
                if (item.name == value) {
                    return true;
                }
            })
            if (!component) {
                return;
            }
            this.componentProps[component.name] = component.props;
            record.eventValue = "";
        },
        valueSourceChange(record) {
            record.eventValue = "";
            if (record.component) {
                record.component = "";
            }
        }
    }
}
</script>

<style lang="less">
.rightDesign{
    padding: 10px;
}
.eventFuncDialog-name {
    height: 40px;
    line-height: 40px;
    width: 100%;
    background-color: #f8f8f8;
    border-radius: 4px;
    border: solid 1px #dedede;
    padding-left: 14px;
    color: #333333;
}

.eventFuncDialog-panel {
    border-radius: 4px;
    border: solid 1px #dedede !important;
    margin-bottom: 16px;

    .ant-collapse-header {
        border-bottom: solid 1px #dedede;
        height: 50px;
        position: relative;
        padding: 14px 13px 14px 10px !important;
    }

    .ant-collapse-arrow {
        left: 13px !important;
    }
}

.eventFuncDialog-extra {
    display: flex;
    align-content: center;
    height: 50px;
    width: calc(100% - 50px);
    position: absolute;
    left: 30px;
    top: 0px;
}

.eventFuncDialog-file {
    display: flex;
    flex: 1;
    line-height: 50px;
    height: 50px;
    margin-left: 5px;
    align-content: center;
}

.delMethod {
    color: #ff3d3d;
    margin-left: 20px;
    font-size: 20px;
    margin-top: 14px;
}

.table-name {
    line-height: 30px;
    width: 100%;
    background-color: #f8f8f8;
    border-radius: 4px;
    border: solid 1px #dedede;
    padding-left: 14px;
    color: #333333;
}
</style>
